home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / info-service / gopher / Unix / GopherTools / gmail-1.01.shar / gmailcal < prev   
Encoding:
Text File  |  1993-03-30  |  12.2 KB  |  384 lines

  1. #!/usr/local/bin/perl
  2. #
  3. #  gmailcal: nightly process to generate alternate views of events
  4. #             submitted with gmail(8)
  5. #
  6. #  usage:  gmailcal
  7. #
  8. #  PASR 01/29/93  Original version (Prentiss Riddle, riddle@rice.edu).
  9. #  PASR 02/03/93  Declared this release 0.2 and sent it out for beta
  10. #                 testing.
  11. #  PASR 02/22/93  Declared this release 1.0 for general use.
  12. #  PASR 02/24/93  Portability fix: match year in ctime() results with a
  13. #                 pattern rather than a substr() call.
  14. #  PASR 03/07/93  Defined umask in the configuration section.
  15. #  PASR 03/29/93  Fixed bug in calculation of week cuts.
  16. #                 Declared this version 1.01.
  17. #
  18. #  TODO: Make sure all old .cache files get deleted when gmailcal is run.
  19. #  TODO: Think about including a command-line option which causes header
  20. #        info to be read from a file, allowing a single installation to
  21. #        be used in multiple configurations (in particular, to allow 
  22. #        multiple events calendars).
  23. #  TODO: Think about putting a chmod in &fixcap.
  24.  
  25. #--------------------------------------------------------------------------
  26. # CONFIGURATION: modify these to suit your site!
  27.  
  28. # Raw calendar data live under here.  Note that the alternate views will
  29. # be *sibling* directories to this one!
  30. $caldir = "/foo/cwis/gopher/world/Calendars/Events/Upcoming";
  31.  
  32. # Gopher link information: a Gopher's-eye view of the same directory
  33. # specified in $caldir.
  34. $Host = "cwis.foobar.edu";
  35. $Port = 70;
  36. $Path = "1/Calendars/Events/Upcoming";
  37.  
  38. # How many days will we keep old events around in the "../Past" directory?
  39. $keepold = 183;
  40.  
  41. # On which day does the week begin?  (0=Sunday, 1=Monday)
  42. $weekbreak = 1;
  43.  
  44. # How many months ahead will we maintain month-by-month views?
  45. $monthviews = 5;
  46.  
  47. # Short description of this events calendar
  48. # (e.g., "the Foobar University events schedule")
  49. $description = "the Foobar University events calendar";
  50.  
  51. # Turn on for noisy output, off for only serious error messages.
  52. $debug = 0;
  53.  
  54. # Umask: the Unix file permissions mask.  Use 002 if you wish to have
  55. # files created by gmailcal be group-writeable, 022 otherwise.
  56. $UMASK = 022;
  57.  
  58. #--------------------------------------------------------------------------
  59. # Further initialization (you should probably leave this alone):
  60.  
  61. require "ctime.pl";
  62.  
  63. @monthnames =
  64.      ("January", "February", "March", "April", "May", "June",
  65.       "July", "August", "September", "October", "November", "December");
  66.  
  67. # Recursive "rm" command (very scary!)
  68. $rm = "/bin/rm -r -f";
  69.  
  70. umask $UMASK;
  71.  
  72. # Master "About" file.  We will put a link to this in each of the alternate
  73. # view subdirectories.
  74. $about = $caldir;
  75. $about =~ s#(.*)/.*#$1/About#;
  76. print(STDERR "Warning: \"About\" file $about missing\n") unless (-f $about);
  77.  
  78. #--------------------------------------------------------------------------
  79. #
  80. # Here's the directory structure we're shooting for:
  81. #
  82. # Foobar Events/
  83. #    About the Foobar events schedule
  84. #    Search the Foobar events schedule <?>
  85. #    Today/
  86. #    Tomorrow/
  87. #    This week/
  88. #    Next week/
  89. #    January, 1993/
  90. #    February, 1993/
  91. #    March, 1993/
  92. #    ...
  93. #    All upcoming events/
  94. #    Past events/
  95.  
  96. # We do all of our work relative to $chdir.
  97. chdir($caldir) || die("Couldn't chdir to $caldir: $!");
  98.  
  99. # Get various date information relative to today's date.
  100. $daysec = 24 * 60 * 60;
  101. $clocktime = time;
  102. $weekday = substr(&ctime($clocktime), 0, 3);
  103. $wkdint = index("SunMonTueWedThuFriSat", $weekday) / 3;
  104. die("Unrecognized weekday: $weekday") if ($wkdint < 0);
  105.  
  106. $today = &yyyymmdd($clocktime);
  107. $tomorrow = &yyyymmdd($clocktime + $daysec);
  108. $pastcut = &yyyymmdd($clocktime - $keepold * $daysec);
  109. $thisweekcut = &yyyymmdd($clocktime + (6 - $wkdint + $weekbreak) * $daysec);
  110. $nextweekcut = &yyyymmdd($clocktime + (13 - $wkdint + $weekbreak) * $daysec);
  111.  
  112. $mm = substr($today, 5, 2);
  113. $yyyy = substr($today, 0, 4);
  114. $monthcuts[0] = substr($today, 0, 7);
  115. for ($i = 1 ; $i < $monthviews ; $i++) {
  116.     #$mm .= "";    # Force into a string context!
  117.     $mm++;
  118.     if ($mm gt "12") {
  119.         $mm = "01";
  120.         $yyyy++;
  121.     }
  122.     $monthcuts[$i] = $yyyy . "-" . $mm;
  123. }
  124.  
  125. # Delete old month directories and corresponding .cap files.
  126. opendir(PARENT, "..") || die("Couldn't open parent directory: $!");
  127. foreach $dir (grep(/^\d\d\d\d-\d\d$/, readdir(PARENT))) {
  128.     print("Deleting: ../$dir ../cap/$dir\n") if $debug;
  129.     system("$rm ../$dir");
  130.     unlink("../.cap/$dir");
  131. }
  132. closedir(PARENT);
  133.  
  134. # Arrange the directories where the alternate views will go.
  135. &fixcap("../About", "About " . $description, 1);
  136. $todaydir = "../Today";        &fixdir($todaydir, "Today", 2);
  137. $tomorrowdir = "../Tomorrow";  &fixdir($tomorrowdir, "Tomorrow", 3);
  138. $thisweekdir = "../This_week"; &fixdir($thisweekdir, "This week", 4);
  139. $nextweekdir = "../Next_week"; &fixdir($nextweekdir, "Next week", 5);
  140. for ($i = 0 ; $i < $monthviews ; $i++) {
  141.     $monthdirs[$i] = "../" . $monthcuts[$i];
  142.     $monthtitles[$i] = $monthnames[substr($monthcuts[$i], 5, 2) - 1]
  143.                        . ", " . substr($monthcuts[$i], 0, 4);
  144.     &fixdir($monthdirs[$i], $monthtitles[$i], $i + 6);
  145. }
  146. &fixcap($caldir, "All upcoming events", $monthviews + 6);
  147. $pastdir = "../Past"; &fixdir($pastdir, "Past events", $monthviews + 7);
  148.  
  149. # Open .links files and put a link to the "About" file in each one.
  150. &openlink("UPCOMING", "$caldir/.links"); close(UPCOMING);
  151. &openlink("PAST", "$pastdir/.links"); close(PAST);
  152. &openlink("TODAY", "$todaydir/.links");
  153. &openlink("TOMORROW", "$tomorrowdir/.links");
  154. &openlink("THISWEEK", "$thisweekdir/.links");
  155. &openlink("NEXTWEEK", "$nextweekdir/.links");
  156. $month = 0;
  157. &openlink("MONTH", "$monthdirs[$month]/.links");
  158.  
  159. # MAIN LOOP: Step through the calendar events in $caldir, creating links
  160. #            to them as necessary.
  161. opendir(CALDIR, ".") || die("Couldn't open $caldir: $!");
  162. MAINLOOP:
  163. foreach $event sort(grep(/^\d\d\d\d-\d\d-\d\d/, readdir(CALDIR))) {
  164.     print("Processing event: \"$event\"\n") if $debug;
  165.     $matchdate = substr($event, 0, 10);
  166.     if ($matchdate lt $today) {
  167.         # Move this event to $pastdir, including its .cap file.
  168.         print "Moving past event: \"$event\"\n" if $debug;
  169.         rename($event, "$pastdir/$event") || 
  170.             die("Can't move $event to $pastdir: $!");
  171.         rename(".cap/$event", "$pastdir/.cap/$event");
  172.     } else {
  173.         # Does the event match today, tomorrow, this or next week?
  174.         if ($matchdate eq $today) {
  175.             &makelink($event, "TODAY");
  176.         } elsif ($matchdate eq $tomorrow) {
  177.             &makelink($event, "TOMORROW");
  178.         }
  179.         if ($matchdate le $thisweekcut) {
  180.             &makelink($event, "THISWEEK");
  181.         } elsif ($matchdate gt $thisweekcut && $matchdate le $nextweekcut) {
  182.             &makelink($event, "NEXTWEEK");
  183.         }
  184.         # Match "../yyyy-mm" against the current $monthdirs[].
  185.         $matchdate = "../" . substr($event, 0, 7);
  186.         while ($matchdate gt $monthdirs[$month] && $month < $monthviews - 1) {
  187.             # New month.
  188.             $month++;
  189.             close(MONTH);
  190.             &openlink("MONTH", "$monthdirs[$month]/.links");
  191.         }
  192.         if ($matchdate eq $monthdirs[$month]) {
  193.             &makelink($event, "MONTH");
  194.         }
  195.     }
  196. }
  197. closedir(CALDIR);
  198. close(TODAY);
  199. close(TOMORROW);
  200. close(THISWEEK);
  201. close(NEXTWEEK);
  202. close(MONTH);
  203.  
  204. # Remove ancient events from the "Past events" directory (including
  205. # their .cap files).
  206. opendir(PAST, $pastdir) || die("Couldn't open directory $pastdir: $!");
  207. PASTLOOP:
  208. foreach $event (grep(/^\d\d\d\d-\d\d-\d\d/, readdir(PAST))) {
  209.     if ($event lt $pastcut) {
  210.         print("Deleting old event: $pastdir/$event\n") if $debug;
  211.         unlink("$pastdir/$event");
  212.         unlink("$pastdir/.cap/$event");
  213.     }
  214. }
  215. closedir(PAST);
  216.  
  217. #--------------------------------------------------------------------------
  218. # fixcap -- fill out a ".cap" file, given a filename, title and position
  219. #
  220. # usage:  &fixcap($filename, $title, $position);
  221.  
  222. sub fixcap {
  223.     local($filename, $title, $position) = @_;
  224.     local($dirname);
  225.  
  226.     print "fixcap(\"$filename\", \"$title\", $position);\n" if $debug;
  227.     # Insert ".cap/" in the filename.
  228.     $filename =~ s#(.*)/(.*)#$1/.cap/$2#;
  229.     $dirname = $filename;
  230.     $dirname =~ s#(.*/\.cap)/.*#$1#;
  231.     unless (-d $dirname) {
  232.         mkdir($dirname, 0755) ||
  233.             die("Can't create .cap directory $dirname: $!");
  234.     }
  235.     open (CAP, "> $filename") || die("Can't open .cap file $filename: $!");
  236.     print(CAP "Name=$title\nNumb=$position\n");
  237.     close (CAP);
  238. }
  239. #--------------------------------------------------------------------------
  240. # fixdir -- prepare a directory which is to contain an alternate view
  241. #
  242. # Side effects:
  243. # -- creates the named directory, if necessary
  244. # -- creates a ".cap" subdirectory within the named directory, if necessary
  245. # -- deletes a ".links" file within the named directory, if necessary
  246. # -- calls &fixcap to set the title and position of the named directory
  247. #    within its parent directory
  248. #
  249. # usage: &fixdir($directory, $title, $position);
  250.  
  251. sub fixdir {
  252.     local($directory, $title, $position) = @_;
  253.  
  254.     unless (-d $directory) {
  255.         mkdir($directory, 0755) || 
  256.             die("Can't create directory $directory: $!");
  257.     }
  258.     unless (-d "$directory/.cap") {
  259.         mkdir("$directory/.cap", 0755) || 
  260.             die("Can't create directory $directory/.cap: $!");
  261.     }
  262.     unlink("$directory/.links") if (-f "$directory/.links");
  263.     print "fixdir(\"$directory\", \"$title\", $position);\n" if $debug;
  264.     &fixcap($directory, $title, $position);
  265. }
  266. #--------------------------------------------------------------------------
  267. # makelink -- make a link to a given event in a given .links file
  268. #
  269. # usage: &makelink($event, $filehandle);
  270. #
  271. # global variables used: $caldir $Host $Port $Path $eventpath $debug
  272.  
  273. sub makelink {
  274.     local($event, $fh) = @_;
  275.     local($name);
  276.  
  277.     print "makelink(\"$event\", \"$fh\");\n" if $debug;
  278.  
  279.     # Read the name from the .cap file corresponding to the event.
  280.     open(CAP, "< $caldir/.cap/$event");
  281.     CAPLOOP:
  282.     while (<CAP>) {
  283.         if (/^Name=/) {
  284.             $name = $_;
  285.             $name =~ s/^Name=//;
  286.             last CAPLOOP;
  287.         }
  288.     }
  289.     close(CAP);
  290.  
  291.     # Complain and exit if we couldn't read it.
  292.     unless ($name) {
  293.         print(STDERR "Error: Couldn't read .cap file for $event\n");
  294.         return;
  295.     }
  296.  
  297.     print($fh "#\n");
  298.     print($fh "Name=$name");
  299.     print($fh "Host=$Host\n");
  300.     print($fh "Type=0\n");
  301.     print($fh "Port=$Port\n");
  302.     unless ($eventpath) {
  303.         $eventpath = $Path;
  304.         $eventpath =~ s/^1/0/;
  305.     }
  306.     print($fh "Path=$eventpath/$event\n");
  307. }
  308. #--------------------------------------------------------------------------
  309. # monthindex -- given a three-character month abbreviation, return the
  310. #               corresponding integer "01" (January) to "12" (December)
  311. #
  312. # usage: $mm = &monthindex($monthstr);
  313. # error: return -1 in case of error;
  314.  
  315. sub monthindex {
  316.     local($monthstr) = @_;
  317.     local($mm);
  318.     $monthstr =~ tr/A-Z/a-z/;
  319.     $mm = index("janfebmaraprmayjunjulaugsepoctnovdec", $monthstr) / 3 + 1;
  320.     $mm = -1 if ($mm <= 0 || $mm > 12);
  321.     $mm = "0" . $mm if ($mm > 0 && $mm < 10);
  322.     return $mm;
  323. }
  324. #--------------------------------------------------------------------------
  325. # openlink -- open a ".links" file
  326. #
  327. # usage:  &openlink($filehandle, $filename);
  328. #
  329. # Global variables used:  $about $description $Host $Port $Path $aboutpath
  330. #
  331. # Side effects:
  332. # -- Opens the .links file specified by $filename
  333. # -- Writes to it a link to the "About" file
  334.  
  335. sub openlink {
  336.     local($fh, $filename) = @_;
  337.  
  338.     print "openlink(\"$fh\", \"$filename\");\n" if $debug;
  339.     open($fh, "> $filename") || 
  340.         die("Can't open .links file $filename: $!");
  341.     print($fh "# This file is automatically generated. Don't touch!\n");
  342.     print($fh "#\n");
  343.     # Kluge alert: for some reason "Numb=1" doesn't work here, so
  344.     # we resort to the old initial-space-in-a-Name trick. :-(
  345.     print($fh "Name= About $description\n");
  346.     #print($fh "Numb=1\n");
  347.     print($fh "Type=0\n");
  348.     print($fh "Host=$Host\n");
  349.     print($fh "Port=$Port\n");
  350.     unless ($aboutpath) {
  351.         $aboutpath = $Path;
  352.         $aboutpath =~ s#(.*)/.*#$1/About#;
  353.         $aboutpath =~ s/^1/0/;
  354.     }
  355.     print($fh "Path=$aboutpath\n");
  356. }
  357. #--------------------------------------------------------------------------
  358. # yyyymmdd -- given a clocktime (in seconds since the epoch), return the
  359. #             corresponding date in the format "yyyy-mm-dd"
  360. #
  361. # usage: $date = &yyyymmdd($clocktime);
  362. #
  363. #
  364. # Portability issue: we count on &ctime() to return the date in one of
  365. # the two following formats:
  366. #
  367. #    Wed Feb 24 10:42:22 1993
  368. #    Wed Feb 24 10:42:22 CST 1993
  369. #
  370. # If it doesn't, we're in trouble...
  371.  
  372. sub yyyymmdd {
  373.     local($clocktime) = @_;
  374.     local($date, $yyyy, $mm, $dd);
  375.     $date = &ctime($clocktime);
  376.     ($yyyy) = $date =~ /\s(\d\d\d\d)\s*$/;
  377.     $mm = &monthindex(substr($date, 4, 3));
  378.     $dd = substr($date, 8, 2);
  379.     $dd =~ s/ /0/;
  380.     return($yyyy . "-" . $mm . "-" . $dd);
  381. }
  382. #--------------------------------------------------------------------------
  383. # end of gmailcal script
  384.